<template>
  <vxe-grid
    ref="$grid"
    v-bind="getBindGridValues"
    :class="getExtraConfig.isFilterAndSort ? 'filter-table' : ''"
  >
    <template #[item]="data" v-for="item in Object.keys($slots)">
      <slot :name="item" v-bind="data || {}"></slot>
    </template>

    <template #toolbar_buttons>
      <div style="display: flex; align-items: center">
        <slot name="title_left"></slot>
        <BasicTitle v-if="getExtraConfig.title" :title="getExtraConfig.title" />
        <slot name="title_right"></slot>
      </div>
    </template>

    <template #tools>
      <div>
        <slot name="tools_left"></slot>
        <el-button
          v-if="getExtraConfig.isExport"
          type="primary"
          :icon="'Download'"
          @click="$grid?.exportData"
          >{{ $t('system.导出') }}</el-button
        >
        <el-button
          v-if="getExtraConfig.isCustom"
          plain
          type="primary"
          :icon="'Operation'"
          @click="$grid?.openCustom"
          >{{ $t('system.列设置') }}</el-button
        >
        <slot name="tools_right"></slot>
      </div>
    </template>
  </vxe-grid>
</template>

<script setup lang="ts">
  defineOptions({
    // name: 'VxeGrid'
    inheritAttrs: false
  })

  import { computed, ref } from 'vue'
  import { VxeGrid, VxeGridProps, VxeGridInstance, VxeGridEventProps } from 'vxe-table'
  import tableProps from 'vxe-table/es/table/src/props'
  import { omit, camelCase, merge, clone } from 'xe-utils'
  import { defaultExtraConfig } from './props'
  import { BasicGridProps, ExtraConfig } from './types'
  import { basicEmits } from './emits'
  import { $t } from '@/locales'
  import { addColumnsParams } from '../../utils/addColumnsParams'

  // 防止丢失组件原始默认值 不使用props类型 使用props 选项对象
  // 不使用外面引入变量,会丢失template中的类型
  const props = defineProps({
    ...tableProps,
    // 新增属性
    extraConfig: {
      type: Object as PropType<ExtraConfig>,
      default: () => ({})
    }
  })
  const attrs = useAttrs()
  const emits = defineEmits(basicEmits)

  const $grid = ref<VxeGridInstance>()
  const emitEvents: VxeGridEventProps = {}

  basicEmits.forEach((name) => {
    const type = camelCase(`on-${name}`) as keyof VxeGridEventProps

    emitEvents[type] = (...args: any[]) => emits(name, ...args)
  })

  const getBindGridEvent: VxeGridEventProps = {
    ...emitEvents
  }

  const getBindValues = computed<BasicGridProps>(() => {
    const propsData: BasicGridProps = {
      ...attrs,
      ...props
    }

    // 合并默认配置
    // merge 连续合并有问题,连续嵌套时后面的键会覆盖前面相同的键
    return merge(clone(defaultExtraConfig, true), propsData)
  })

  const getBindGridValues = computed<VxeGridProps>(() => {
    const omitProps: BasicGridProps = omit(getBindValues.value, ['extraConfig'])

    // 添加前端筛选和排序
    if (getExtraConfig.value.isFilterAndSort) {
      omitProps.columns && (omitProps.columns = addColumnsParams(omitProps.columns))
    }

    return {
      ...omitProps,
      ...getBindGridEvent
    }
  })

  const getExtraConfig = computed<ExtraConfig>(() => {
    const { extraConfig } = getBindValues.value

    return extraConfig || {}
  })

  const tableExpose = {
    /** 外部传递给组件的属性 */
    getBindValues,
    /** 组件传递给表格经过处理后的属性 */
    getBindGridValues,
    $grid
  }

  defineExpose(tableExpose)
</script>
<!-- 
<style lang="scss" scoped>
  .table-top {
    // margin-bottom: 16px;
  }
</style> -->
